"""
webserver
"""
# 接收客户端浏览器发送请求
# 解析客户端大宋的请求
# 根据请求组织数据内容
# 讲数据内容形成http响应格式返回给浏览器
# 要求
    #采用类封装
    #使用IO并发网络模型

from socket import *
from select import *


class Handle():
    def __init__(self, ep, map,html):
        self.html = html
        self._ep = ep
        self.map = map

    def close(self,fd):
        self._ep.unregister(fd)  # 不再关注
        self.map[fd].close()
        del self.map[fd]  # 维护字典


    # 处理数据收发
    def handle(self, fd):
        # 浏览器的http请求
        request = self.map[fd].recv(1024).decode()
        if not request:
            self.close(fd)
            return
        info=request.split(' ')[1]
        print('请求内容')




# 搭建网络结构
class WebServer:
    def __init__(self, host='', port=0, html=None):
        self.host = host
        self.port = port
        self.address = (host, port)
        self.html = html # 网页位置
        self._ep = epoll()
        self.map = {}  # 存储文件描述符和对象的对应关系
        self.sock = self._create_socket()
        self._handle = Handle(self._ep, self.map,html)

    def _create_socket(self):
        sock = socket()
        sock.bind(self.address)
        sock.setblocking(False)  # 非阻塞
        return sock

    # 处理客户端连接
    def _connect(self, fd):
        # 监听套接字对象就绪 ：连接客户端
        conn, addr = self.map[fd].accept()
        conn.setblocking(False)
        # 关注conn读
        self._ep.register(conn, EPOLLIN)
        self.map[conn.fileno()] = conn  # 维护字典

    # 主体服务
    def serve_forever(self):
        self.sock.listen(5)
        self._ep.register(self.sock, EPOLLIN)
        self.map[self.sock.fileno()] = self.sock
        print("Listen the port %d" % self.port)
        # 循环监控IO对象的发生
        while True:
            events = self._ep.poll()  # [(fileno,event),()]
            for fd, event in events:
                if fd == self.sock.fileno():
                    self._connect(fd)
                else:
                    self._handle.handle(fd)


if __name__ == '__main__':
    httpd = WebServer(host="0.0.0.0", port=8888, html="./static")
    httpd.serve_forever()  # 允许浏览器连接